package com.luhuiguo.cms.client.presenter;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasHTML;
import com.google.gwt.user.client.ui.HasValue;
import com.google.inject.Inject;
import com.luhuiguo.cms.client.AppConstants;
import com.luhuiguo.cms.client.AppMessages;
import com.luhuiguo.cms.shared.event.ArticleCreatedEvent;
import com.luhuiguo.cms.shared.event.ArticleUpdatedEvent;
import com.luhuiguo.cms.shared.event.EditArticleCancelledEvent;
import com.luhuiguo.cms.shared.event.FlashEvent;
import com.luhuiguo.cms.shared.model.ArticleModel;
import com.luhuiguo.cms.shared.rpc.CreateArticle;
import com.luhuiguo.cms.shared.rpc.CreateArticleResult;
import com.luhuiguo.cms.shared.rpc.UpdateArticle;
import com.luhuiguo.cms.shared.rpc.UpdateArticleResult;
import com.luhuiguo.gwt.dispatcher.client.DispatcherAsync;
import com.luhuiguo.gwt.presenter.client.EventBus;
import com.luhuiguo.gwt.presenter.client.widget.WidgetDisplay;
import com.luhuiguo.gwt.presenter.client.widget.WidgetPresenter;
import com.luhuiguo.gwt.validation.client.ValidationProcessor;

public class EditArticlePresenter extends WidgetPresenter<EditArticlePresenter.Display> {

    public interface Display extends WidgetDisplay {

        HasClickHandlers getSubmitButton();

        HasClickHandlers getCancelButton();

        HasValue<String> getTitleField();

        HasValue<String> getSubjectField();

        HasValue<String> getAuthorField();

        HasValue<String> getSourceField();

        HasValue<String> getKeywordsField();

        HasValue<String> getDescriptionField();

        HasHTML getContentField();

        // HasValue<String> getStatusField();
        //
        // HasValue<Date> getPublishDateField();

        ValidationProcessor getValidator();

        boolean validate();

        void setLoading(boolean loading);

    }

    private DispatcherAsync dispatcher;

    private AppConstants constants;

    private AppMessages messages;

    private ArticleModel article;

    @Inject
    public EditArticlePresenter(Display display, EventBus eventBus, DispatcherAsync dispatcher, AppConstants constants,
            AppMessages messages) {
        super(display, eventBus);
        this.dispatcher = dispatcher;
        this.constants = constants;
        this.messages = messages;
        GWT.log("EditArticlePresenter created");

    }

    @Override
    protected void onBind() {
        GWT.log("EditArticlePresenter onBind");
        registerHandler(display.getSubmitButton().addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                if (display.validate()) {
                    if (null == article.getId()) {
                        createArticle();
                    } else {
                        updateArticle();
                    }
                }
            }
        }));

        registerHandler(display.getCancelButton().addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                eventBus.fireEvent(new EditArticleCancelledEvent(article.getChannel()));
            }
        }));

    }

    @Override
    protected void onRevealDisplay() {
        GWT.log("EditArticlePresenter onRevealDisplay");
    }

    protected void revealDisplay(ArticleModel article) {
        this.article = article;
        loadModel(article);
        revealDisplay();
    }

    @Override
    protected void onUnbind() {

    }

    protected void loadModel(ArticleModel article) {
        display.getTitleField().setValue(article.getTitle());
        display.getSubjectField().setValue(article.getSubject());
        display.getAuthorField().setValue(article.getAuthor());
        display.getSourceField().setValue(article.getSource());
        display.getKeywordsField().setValue(article.getKeywords());
        display.getDescriptionField().setValue(article.getDescription());
        display.getContentField().setHTML(article.getContent());
    }

    protected void updateModel(ArticleModel article) {
        article.setTitle(display.getTitleField().getValue());
        article.setSubject(display.getSubjectField().getValue());
        article.setAuthor(display.getAuthorField().getValue());
        article.setSource(display.getSourceField().getValue());
        article.setKeywords(display.getKeywordsField().getValue());
        article.setDescription(display.getDescriptionField().getValue());
        article.setContent(display.getContentField().getHTML());
    }

    private void createArticle() {
        display.setLoading(true);

        updateModel(article);

        dispatcher.execute(new CreateArticle(article), new AsyncCallback<CreateArticleResult>() {

            @Override
            public void onFailure(Throwable caught) {
                display.setLoading(false);
                eventBus.fireEvent(new FlashEvent(messages.saveChannelFailed(article.getTitle()), -1));
            }

            @Override
            public void onSuccess(CreateArticleResult result) {
                display.setLoading(false);
                eventBus.fireEvent(new ArticleCreatedEvent(result.get()));
                doReset();

            }
        });

    }

    private void updateArticle() {
        display.setLoading(true);

        updateModel(article);

        dispatcher.execute(new UpdateArticle(article), new AsyncCallback<UpdateArticleResult>() {

            @Override
            public void onFailure(Throwable caught) {
                display.setLoading(false);
                eventBus.fireEvent(new FlashEvent(messages.saveArticleFailed(article.getTitle()), -1));

            }

            @Override
            public void onSuccess(UpdateArticleResult result) {
                display.setLoading(false);
                eventBus.fireEvent(new ArticleUpdatedEvent(result.getNew()));
                doReset();

            }
        });

    }

    private void doReset() {
        display.getTitleField().setValue("");
        display.getSubjectField().setValue("");
        display.getAuthorField().setValue("");
        display.getSourceField().setValue("");
        display.getKeywordsField().setValue("");
        display.getDescriptionField().setValue("");
        display.getContentField().setHTML("");
        display.getValidator().reset();
    }

}
